import csv
import io
from decimal import Decimal

# 富途持仓明细类
# 表示用户持有的某只股票的详细信息
class FutuStockPosition:
    def __init__(self):
        # 股票代码
        self.code = ""
        # 股票名称
        self.name = ""
        # 持有数量
        self.quantity =  Decimal(0)
        # 当前市价
        self.market_price =  Decimal(0)
        # 市值 = 持有数量 * 市价
        self.market_value =  Decimal(0)
        # 可用数量
        self.available_quantity =  Decimal(0)
        # 未实现盈亏比例
        self.unrealized_profit_ratio =  Decimal(0)
        # 今日盈亏
        self.today_profit =  Decimal(0)
        # 平均成本价
        self.average_cost =  Decimal(0)
        # 总盈亏金额
        self.total_profit =  Decimal(0)
        # 未实现盈亏
        self.unrealized_profit = Decimal(0)
        # 已实现盈亏
        self.realized_profit =  Decimal(0)
        # 持仓占比
        self.position_ratio = Decimal(0)
        # 今日成交额
        self.today_turnover =  Decimal(0)
        # 今日买入数量
        self.today_buy_quantity =  Decimal(0)
        # 今日买入均价
        self.today_buy_average_price =  Decimal(0)
        # 今日卖出数量
        self.today_sell_quantity =  Decimal(0)
        # 今日卖出均价
        self.today_sell_average_price =  Decimal(0)
        # 交易币种
        self.currency = ""
        # 市场类型
        self.market = ""
        # 股东代码
        self.shareholder_code = ""

    def __str__(self):
        return (f"FutuStockPosition(code={self.code}, name={self.name}, quantity={self.quantity}, "
                f"market_price={self.market_price}, market_value={self.market_value}, "
                f"available_quantity={self.available_quantity}, "
                f"unrealized_profit_ratio={self.unrealized_profit_ratio}, today_profit={self.today_profit}, "
                f"average_cost={self.average_cost}, total_profit={self.total_profit}, "
                f"unrealized_profit={self.unrealized_profit}, realized_profit={self.realized_profit}, "
                f"position_ratio={self.position_ratio}, today_turnover={self.today_turnover}, "
                f"today_buy_quantity={self.today_buy_quantity}, "
                f"today_buy_average_price={self.today_buy_average_price}, "
                f"today_sell_quantity={self.today_sell_quantity}, "
                f"today_sell_average_price={self.today_sell_average_price}, currency={self.currency}, "
                f"market={self.market}, shareholder_code={self.shareholder_code})")

# 富途股票持仓解析器
class FutuStockPositionParser:
    def parse(self, file):
        """
        解析富途股票持仓 CSV 文件
        :param file: 文件对象或文件路径
        :return: 包含富途股票持仓信息的列表
        """
        if isinstance(file, str):
            # 如果传入的是文件路径，打开文件
            with open(file, 'r', encoding='utf-8') as f:
                content = f.read()
        else:
            # 如果传入的是文件对象，读取文件内容
            content = file.read()

        reader = csv.reader(io.StringIO(content))
        try:
            header = next(reader)
        except StopIteration:
            return []

        header = [item.strip() for item in header]
        header_index = {name: index for index, name in enumerate(header)}
        positions = []
        for row in reader:
            if not row:
                continue
            # 解析每行数据
            positions.append(self.parse_stock_position(row, header_index))
        return positions

    def parse_stock_position(self, row, header_index):
        """
        解析一行股票持仓数据
        :param row: 包含股票持仓信息的列表
        :param header_index: 表头与列索引的映射
        :return: 富途股票持仓信息对象
        """
        position = FutuStockPosition()
        position.code = self.get_value(row, header_index, "代码")
        position.name = self.get_value(row, header_index, "名称")

        holding_value = self.get_value(row, header_index, "持有数量@市价", default="0@0")
        holding_quantity, holding_price = self.split_pair(holding_value)
        position.quantity = self.parse_number(holding_quantity)
        position.market_price = self.parse_decimal(holding_price)

        position.market_value = self.parse_decimal(self.get_value(row, header_index, "市值"))
        position.available_quantity = self.parse_number(self.get_value(row, header_index, "可用数量"))
        position.unrealized_profit_ratio = self.parse_percentage(self.get_value(row, header_index, "未实现盈亏比例"))
        position.today_profit = self.parse_decimal(self.get_value(row, header_index, "今日盈亏"))
        position.average_cost = self.parse_decimal(self.get_value(row, header_index, "平均成本价"))
        position.total_profit = self.parse_decimal(self.get_value(row, header_index, "总盈亏金额"))
        position.unrealized_profit = self.parse_decimal(self.get_value(row, header_index, "未实现盈亏"))
        position.realized_profit = self.parse_decimal(self.get_value(row, header_index, "已实现盈亏"))
        position.position_ratio = self.parse_percentage(self.get_value(row, header_index, "持仓占比"))
        position.today_turnover = self.parse_decimal(self.get_value(row, header_index, "今日成交额"))

        buy_value = self.get_value(row, header_index, "今日买入@均价", default="--@--")
        buy_quantity, buy_average_price = self.split_pair(buy_value)
        position.today_buy_quantity = self.parse_number(buy_quantity)
        position.today_buy_average_price = self.parse_decimal(buy_average_price)

        sell_value = self.get_value(row, header_index, "今日卖出@均价", default="--@--")
        sell_quantity, sell_average_price = self.split_pair(sell_value)
        position.today_sell_quantity = self.parse_number(sell_quantity)
        position.today_sell_average_price = self.parse_decimal(sell_average_price)

        position.currency = self.get_value(row, header_index, "币种")
        position.market = self.get_value(row, header_index, "市场")
        position.shareholder_code = self.get_value(row, header_index, "股东代码")
        return position

    def get_value(self, row, header_index, column_name, default=""):
        """
        根据列名获取对应的值
        :param row: 当前行的数据
        :param header_index: 表头与列索引的映射
        :param column_name: 目标列名
        :param default: 默认值
        :return: 对应列的数据或默认值
        """
        index = header_index.get(column_name)
        if index is None or index >= len(row):
            return default
        return row[index].strip()

    def split_pair(self, value, delimiter="@"):
        """
        将形如"数量@价格"的字符串拆分为数量和价格
        :param value: 待拆分的字符串
        :param delimiter: 分隔符
        :return: (数量, 价格)
        """
        parts = value.split(delimiter)
        if len(parts) == 2:
            return parts[0].strip(), parts[1].strip()
        if len(parts) == 1:
            return parts[0].strip(), "0"
        return "0", "0"

    def parse_number(self, value):
        """
        解析数字字符串
        :param value: 数字字符串
        :return: 解析后的整数
        """
        return self.parse_decimal(value)

    def parse_decimal(self, value):
        """
        解析金额或价格等数字字符串
        :param value: 数字字符串
        :return: Decimal 类型的数值
        """
        if value is None:
            return Decimal(0)
        cleaned_value = value.strip()
        if cleaned_value in ("", "--"):
            return Decimal(0)
        return Decimal(self.remove_commas(cleaned_value))

    def parse_percentage(self, value):
        """
        解析百分比字符串
        :param value: 百分比字符串
        :return: 解析后的小数
        """
        if value is None:
            return Decimal(0)
        clean_value = value.strip()
        if clean_value in ("", "--"):
            return Decimal(0)
        # 移除百分号和正负号，转换为小数形式
        clean_value = clean_value.replace("%", "").replace("+", "")
        return Decimal(clean_value) / 100

    def remove_commas(self, value):
        """
        移除字符串中的逗号
        :param value: 包含逗号的字符串
        :return: 移除逗号后的字符串
        """
        return value.replace(",", "")

# 使用示例
if __name__ == "__main__":
    try:
        sample_csv = "../../test/data/report/持仓-富途证券(香港) 保证金综合账户(9257)-2025.06.07 13：50：11.csv"
        parser = FutuStockPositionParser()
        # 解析CSV文件
        list = parser.parse(sample_csv)

        # 打印解析结果
        print("解析成功！")

        print("持仓详情:")
        for stock in list:
            print(f"  {stock}")

    except Exception as e:
        print(f"解析出错: {str(e)}")